<template>
  <div class="page-container">
    <div class="content">
      <b-scorll class="msg-list" ref="listScorll" :pulldown="true" @pulldown="loadHistory">
        <div class="scorll-inner" ref="inner">
          <!-- <div class="person-btn" v-if="!person" @click="personEnter">
            <span>尊敬的客户，欢迎使用东莞证券在线客服，如您需要转接人工客服，<i class="btn-text">请点击此处（转人工服务）</i></span>
          </div> -->
          <div class="queue-msg" v-if="queueNum > 0">
            <span
              >您好，您前面还有<span class="queue-num">{{ queueNum }}</span
              >人在排队，请您耐心等候，也可以通过95328电话联系客服哦。</span
            >
          </div>
          <!-- <div class="pull-tip" v-if="serviceInter && pullTip" @click="loadHistory">
            <span>点击获取历史记录</span>
          </div> -->
          <van-loading type="spinner" v-show="isHistoryLoading && !noshistory" class="pull-loading" size="12px"></van-loading>
          <div class="pull-tip" v-if="isHistoryLoading && noshistory">
            <span>没有更多了</span>
          </div>
          <div v-if="msgList.length">
            <div class="row" v-for="(row, index) in msgList" :key="index" :id="row.msg.id" :ref="'msg' + row.msg.id">
              <!-- 系统消息 -->
              <div v-if="row.type == 'system'">
                <div class="system">
                  <!-- 文字消息 -->
                  <div class="system-text">
                    {{ row.msg.content.text }}
                  </div>
                </div>
              </div>
              <!-- 工具连接消息 -->
              <div v-if="row.type == 'link'">
                <div class="message-link" v-if="row.msg.type == 'link'" @click="linkForward(row.msg)">
                  <!-- 文字消息 -->
                  <div class="link-name">
                    <span>{{ row.msg.content.link.toolName }}</span>
                  </div>
                  <div class="link-btn">
                    <span>点击前往</span>
                  </div>
                </div>
              </div>
              <!-- 用户消息 -->
              <div v-if="row.type == 'user'">
                <!-- 自己发出的消息 -->
                <div class="my" v-if="row.msg.userinfo.uid == smartTalkerId">
                  <!-- 左-消息 -->
                  <div class="left">
                    <!-- 文字消息 -->
                    <div v-if="row.msg.type == 'text'" class="bubble">
                      <div class="rich-text" v-html="row.msg.content.text"></div>
                    </div>
                    <!-- 图片消息 -->
                    <div v-if="row.msg.type == 'img'" class="bubble img" @click="showPic(row.msg)">
                      <img :src="row.msg.content.url" />
                    </div>
                  </div>
                </div>
                <!-- 别人发出的消息 -->
                <div class="other" v-if="row.msg.userinfo.uid != smartTalkerId">
                  <!-- 右-用户名称-时间-消息 -->
                  <div class="right">
                    <!-- 文字消息 -->
                    <div v-if="row.msg.type == 'text'" class="bubble">
                      <div class="rich-text" v-html="row.msg.content.text"></div>
                    </div>
                    <!-- 图片消息 -->
                    <div v-if="row.msg.type == 'img'" class="bubble img" @click="showPic(row.msg)">
                      <img :src="row.msg.content.url" />
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </b-scorll>
    </div>
    <!-- 底部输入栏 fixed定位 bottom 0 -->
    <div class="input-box">
      <!-- 配置按钮 -->
      <div class="padding-container">
        <b-scorll class="config-wrap" :scrollX="true" ref="configScroll">
          <div class="input-config">
            <div class="config-item" @click="onComment">
              <span class="item">服务评价</span>
            </div>
            <div class="config-item" v-for="nav in navList" :key="nav.id" @click="nvaLink(nav)">
              <span class="item">{{ nav.toolName }}</span>
            </div>
          </div>
        </b-scorll>
      </div>
      <div class="input-item">
        <div class="textbox">
          <div class="text-mode">
            <div class="box">
              <textarea ref="textarea" autofocus="autofocus" auto-height="true" v-model.trim="textMsg" @keyup.enter="sendText" />
            </div>
          </div>
        </div>
        <div class="more" :class="showSend ? 'hidden' : ''">
          <div class="icon tupian2" v-if="isAPP" @click="uploader"></div>
          <template v-else>
            <van-uploader :before-read="beforeRead" :after-read="afterRead">
              <div class="icon tupian2"></div>
            </van-uploader>
          </template>
        </div>
        <!--  -->
        <div class="send" :class="showSend ? '' : 'hidden'" @click="sendText">
          <div class="btn">发送</div>
        </div>
      </div>
    </div>
    <!-- 服务评价弹框 -->
    <div class="comment" v-if="commentShow">
      <evaluate :commentInfo="commentInfo" @commentClose="commentClose"></evaluate>
    </div>
    <div class="comment" v-if="imgPreview">
      <preview :imageSrc="imageSrc" @onPreview="onPreview"></preview>
    </div>
  </div>
</template>
<script>
import { wsSend, messageBody, deepClone, msgBody, recoderTimeformat, dataURLtoFile, browser,transTimestamp} from '@/utils/index.js'
import { canvasDataURL } from '@/utils/compress.js'
import mixin from './mixin.js'
import { queryChat, netUploadFile, queryTool } from '@/api/index.js'
import evaluate from './component/evaluate.vue'
import preview from './component/preview.vue'
import BScorll from './component/b-scorll'
import { Dialog, Uploader, Loading, ImagePreview } from 'vant'
export default {
  components: {
    evaluate,
    preview,
    BScorll,
    [Dialog.Component.name]: Dialog.Component,
    [Uploader.name]: Uploader,
    [Loading.name]: Loading,
  },
  mixins: [mixin],
  data() {
    return {
      //文字消息
      textMsg: '',
      //消息列表
      isHistoryLoading: false,
      noshistory: false,
      viewid: '',
      msgList: [],
      msgImgList: [],
      showLoading: false,
      // 请求历史数据
      queryList: [],
      ID: null, // 用户标志码（token）,
      pageNum: 1,
      pageSize: 10,
      person: false,
      commentShow: false,
      hasComment: false,
      commentInfo: {
        meetingId: this.meetingId,
        waiter: this.waiterId,
        member: this.ID,
      },
      showSend: false,
      userName: '',
      navList: [],
      imageData: '',
      imageSrc: '',
      imgPreview: false,
      pullTip: true,
      isApp: true,
      channel: '',
    }
  },
  created() {
    let ticket = ''
    const queryString = window.location.search
    if (queryString.indexOf('ticket') > -1) {
      ticket = queryString.replace(/.*ticket=/, '')
    }
    if ([undefined, 'undefined', null, 'null'].includes(ticket)) {
      ticket = ''
    }
    window.sessionStorage.setItem('ticket', ticket)
    // 获取app的版本号
    window.setAppVersion = function (version) {
      window.sessionStorage.setItem('version', version)
    }
    this.isAPP = browser.isApp
    if (browser.isApp) {
      this.channel = 'app'
    } else if (browser.weixin) {
      this.channel = '微信'
    } else {
      this.channel = '未知平台'
    }
    this.channel
    this.getToken()
  },
  watch: {
    textMsg(val) {
      if (val) {
        this.showSend = true
      } else {
        this.showSend = false
      }
    },
  },
  mounted() {
    this.personEnter()  //将原来的按钮换成直接触发
    if (browser.ios) {
      this.$refs['textarea'].addEventListener(
        'blur',
        () => {
          document.body.scrollIntoView() || document.documentElement.scrollIntoView(false)
        },
        true
      )
      this.$refs['textarea'].addEventListener(
        'focus',
        () => {
          document.body.scrollIntoView() || document.documentElement.scrollIntoView(false)
          this.$nextTick(() => {
                // 滚动到底
            this.$refs.listScorll.scroll && this.$refs.listScorll.scroll.refresh()
            this.$refs.listScorll.scroll && this.$refs.listScorll.scroll.scrollTo(0, this.$refs.listScorll.scroll.maxScrollY, 0)
          })
        },
        true
      )
    } else {
      let eventName = 'orientationchange' in window ? 'orientationchange' : 'resize'
      window.addEventListener(
        eventName,
        () => {
          // 在页面大小发生变化时调用
          const height = document.documentElement.clientHeight
          document.querySelector('.page-container').style.height = height + 'px'
          this.$nextTick(() => {
            // 滚动到底
            this.$refs.listScorll.scroll && this.$refs.listScorll.scroll.refresh()
            this.$refs.listScorll.scroll && this.$refs.listScorll.scroll.scrollTo(0, this.$refs.listScorll.scroll.maxScrollY, 0)
          })
        },
        false
      )
    }
    this.getNavs()
    this.linkLogin()
    // this.getTicket()
    let startY = 0
    let endY = 0
    this.$refs.listScorll.$el.addEventListener(
      'touchstart',
      (e) => {
        startY = e.changedTouches[0].pageY
      },
      false
    )
    this.$refs.listScorll.$el.addEventListener(
      'touchend',
      (e) => {
        endY = e.changedTouches[0].pageY
        const distance = endY - startY
        const y = this.$refs.listScorll.scroll && this.$refs.listScorll.scroll.y
        const istop = !y || y > -10
        if (distance > 50 && this.serviceInter && istop) {
          this.loadHistory()
        }
      },
      false
    )
  },
  methods: {
    getToken() {
      // 进入页面获取token
      let token = ''
      window.getNewToken = (tk) => {
        token = tk
        if (token != '') {
          window.sessionStorage.setItem('token', token)
        }
      }
      window.setToken = (tk) => {
        token = tk
        if (token != '') {
          window.sessionStorage.setItem('token', token)
        }
      }
      if (browser.ios) {
        window.app_init = () => {
          if (window.KDS_Native && window.KDS_Native.getNewLoginAuthToken) {
            window.KDS_Native.getNewLoginAuthToken(false, 'getNewToken')
          } else if (window.KDS_Native && window.KDS_Native.getTokenWxApiNew) {
            window.KDS_Native.getTokenWxApiNew(false, 'getNewToken')
          }
        }
      } else {
        if (window.KDS_Native && window.KDS_Native.getNewLoginAuthToken) {
          window.KDS_Native.getNewLoginAuthToken(false, 'getNewToken')
        } else if (window.KDS_Native && window.KDS_Native.getTokenWxApiNew) {
          window.KDS_Native.getTokenWxApiNew(false, 'getNewToken')
        }
      }
    },
    getTicket() {
      //主动唤起登录
      let ticket = sessionStorage.getItem('ticket')
      // app内调用原生登录，
      let timer = setInterval(() => {
        if (!ticket) {
          if (window.KDS_Native && window.KDS_Native.getTradeAuth) {
            window.KDS_Native.getTradeAuth()
          }
        } else {
          clearInterval(timer)
        }
      }, 500)
      // 准备给app的回调函数，注册到全局window上
      window.setTradeAuth = (tick) => {
        ticket = tick || ''
        if (tick == 'undefined' || tick == 'null') {
          ticket = ''
        }
        if (ticket) {
          sessionStorage.setItem('ticket', ticket)
          window.location.reload()
        }
      }
      window.getTradeAuthCallback = () => {
        this.authFlag = false
      }
    },
    linkLogin() {
      window.setTradeAuth = (ticket) => {
        console.log('调用了setTradeAuth')
        if (ticket == 'undefined' || ticket == 'null') {
          const params = {
            contentType: '0x77',
            content: '验证失败',
          }
          this.wsOpen && wsSend(this.socketTask, params)
        } else {
          const params = {
            contentType: '0x76',
            content: '验证成功',
          }
          this.wsOpen && wsSend(this.socketTask, params)
        }
      }
    },
    // 导航栏
    getNavs() {
      const params = {
        pageSize: 1000,
        pageNum: 1,
        isShow: 1,
      }
      queryTool(params)
        .then((res) => {
          const {
            data: { records },
          } = res
          this.navList = records.filter((item) => item.isShow == 1)
          if (this.$refs.configScroll.scroll) {
            this.$nextTick(() => {
              this.$refs.configScroll.refresh()
            })
          } else {
            this.$nextTick(() => {
              this.$refs.configScroll._initScroll()
            })
          }
        })
        .catch(() => {
          this.$toast('导航栏接口异常')
        })
    },
    nvaLink(nav) {
      const url = browser.ios ? nav.iosUrl : nav.toolUrl
      if (url) {
        // window.open(nav.toolUrl)
        window.KDS_Native.switchDeeplink(url)
      } else {
        this.$toast('地址不存在')
      }
    },
    personEnter() {
      if (this.bigSocketTask && this.bigSocketTask.onOpen) {
        return
      }
      this.person = true
      this.creatBigMeeting()
    },
    commentClose(e) {
      this.commentShow = false
      const { closeType, ...arg } = e
      this.hasComment = closeType
      if (closeType) {
        let msg = { text: arg }
        this.sendMsg(msg, 'comment')
      }
    },
    linkForward(params) {
      const {
        content: {
          link: { iosUrl, toolUrl },
        },
      } = params
      const url = browser.ios ? iosUrl : toolUrl
      if (url) {
        // window.open(nav.toolUrl)
        window.KDS_Native && window.KDS_Native.switchDeeplink(url)
      } else {
        this.$toast('地址不存在')
      }
    },
    // 接受消息(筛选处理)
    screenMsg(msg) {
      //从长连接处转发给这个方法，进行筛选处理
      if (msg.type == 'system') {
        // 系统消息
        switch (msg.msg.type) {
          case 'text':
            this.addSystemTextMsg(msg)
            break
        }
      } else if (msg.type == 'user') {
        // 用户消息
        switch (msg.msg.type) {
          case 'text':
            this.addTextMsg(msg)
            break
          case 'voice':
            this.addVoiceMsg(msg)
            break
          case 'img':
            this.addImgMsg(msg)
            break
        }
      } else if (msg.type == 'link') {
        this.addLinkMsg(msg)
      }
      if (msg.type) {
        if (this.$refs.listScorll.scroll) {
          if (msg.msg.type == 'img') {
            this.$nextTick(() => {
              // 滚动到底
              this.$refs.listScorll.scroll && this.$refs.listScorll.scroll.refresh()
              this.$refs.listScorll.scroll && this.$refs.listScorll.scroll.scrollTo(0, this.$refs.listScorll.scroll.maxScrollY, 300)
            })
          } else {
            this.$nextTick(() => {
              // 滚动到底
              this.$refs.listScorll.scroll && this.$refs.listScorll.scroll.refresh()
              this.$refs.listScorll.scroll && this.$refs.listScorll.scroll.scrollTo(0, this.$refs.listScorll.scroll.maxScrollY, 300)
            })
          }
        } else {
          this.$refs.listScorll._initScroll()
        }
      }
    },
    //触发滑动到顶部(加载历史信息记录)
    async loadHistory() {
      if (this.isHistoryLoading) {
        return
      }
      this.pullTip = false
      this.isHistoryLoading = true //参数作为进入请求标识，防止重复请求
      this.viewid = this.msgList[1] ? this.msgList[1].msg.id : '' //记住第二个信息id,第一条信息是时间，无id
      await this.getHistory()
      //这段代码很重要，不然每次加载历史数据都会跳到顶部
      if (this.$refs.listScorll.scroll) {
        this.$nextTick(() => {
          this.$refs.listScorll.refresh()
          const ele = document.getElementById(this.viewid)
          if (ele) {
            this.$refs.listScorll.scrollToElement(ele, 0, false, -20, 'easing')
          } else {
            this.$refs.listScorll.scroll.scrollTo(0, 0, 0)
          }
        })
      } else {
        this.$refs.listScorll._initScroll()
        this.$nextTick(() => {
          this.$refs.listScorll.refresh()
          const ele = document.getElementById(this.viewid)
          if (ele) {
            this.$refs.listScorll.scrollToElement(ele, 0, false, -20, 'easing')
          } else {
            this.$refs.listScorll.scroll.scrollTo(0, 0, 0)
          }
        })
      }
    },
    // 历史请求
    async getHistory() {
      if (!this.ID || this.noshistory) {
        return
      }
      const [start, end] = recoderTimeformat(new Date())
      const params = {
        talker: this.ID,
        pageNum: this.pageNum,
        pageSize: this.pageSize,
        startTime: start,
        endTime: end,
      }
      await queryChat(params)
        .then((res) => {
          const historyList = res.data.list
          this.queryList = []
          if (this.pageSize > res.data.total) {
            this.noshistory = true
          }
          this.pageSize += 10
          historyList.forEach((item) => {
            let params = {
              id: item.id,
              type: 'user',
              uid: item.talker,
              time: item.serverTime,
            }
            if (item.contentType === '0x41' || item.contentType === '0x79') {
              this.queryList.push(
                messageBody({
                  ...params,
                  content: { text: item.content },
                  talkType: 'text',
                })
              )
            }
            if (item.contentType == '0x45') {
              this.queryList.push(
                messageBody({
                  ...params,
                  content: { url: item.content },
                  talkType: 'img',
                })
              )
            }
            if (item.contentType == '0x42') {
              this.queryList.push(
                messageBody({
                  ...params,
                  content: { url: item.content },
                  talkType: 'voice',
                })
              )
            }
            if (item.contentType == '0x62') {
              params.type = 'link'
              this.queryList.push(
                messageBody({
                  ...params,
                  content: { link: JSON.parse(item.content) },
                  talkType: 'link',
                })
              )
            }
            if (item.contentType === '0x79') {
              //时间消息
              const timemsg = {
                id: item.reserved2,
                type: 'system',
                content: {
                 text: transTimestamp(item.serverTime)
                },
              }
              this.queryList.push(messageBody(timemsg))
            }
          })
          // 消息列表
          let list = deepClone(this.queryList)
          this.msgList = []
          // 获取消息中的图片,并处理显示尺寸
          for (let i = 0; i < list.length; i++) {
            if (list[i].type == 'user' && list[i].msg.type == 'img') {
              list[i].msg.content = this.setPicSize(list[i].msg.content)
              this.msgImgList.unshift(list[i].msg.content.url)
            }
            this.msgList.unshift(list[i])
          }
        })
        .catch(() => {
          this.$toast('历史查询异常')
          this.noshistory = false
        })
        .finally(() => {
          this.isHistoryLoading = false
        })
    },
    //处理图片尺寸，如果不处理宽高，新进入页面加载图片时候会闪
    setPicSize(content) {
      // 让图片最长边等于设置的最大长度，短边等比例缩小，图片控件真实改变，区别于aspectFit方式。
      let maxW = 350 //350是定义消息图片最大宽度
      let maxH = 350 //350是定义消息图片最大高度
      if (content.w > maxW || content.h > maxH) {
        let scale = content.w / content.h
        content.w = scale > 1 ? maxW : maxH * scale
        content.h = scale > 1 ? maxW / scale : maxH
      }
      return content
    },
    beforeRead(file) {
      if (!this.serviceInter) {
        this.$toast('暂未接入客服')
        return false
      }
      if (file.type !== 'image/jpeg') {
        this.$toast('请上传正确格式的图片')
        return false
      }
      return true
    },
    uploader() {
       if (!this.serviceInter) {
        this.$toast('暂未接入客服')
        return false
      }
      //app上传
      window.setImg = (img) => {
        if (typeof img === 'object') {
          img = img.imageData
        }
        this.imageData = img
        this.imageSrc = 'data:image/jpeg;base64,' + img
        const file1 = dataURLtoFile(this.imageData, 'fileName')
        // console.log('压缩前',file1)
        if (file1.size > 10 * 1024 * 1024) {
          this.$toast('图片尺寸过大')
          return
        } else {
          this.imgPreview = true
        }
      }
      if (window.KDS_Native) {
        // window.KDS_Native.startPhone()
        //这一步会执行window.setImg
        window.KDS_Native.startPhotoAlbum()
      }
    },
    afterRead(file) {
      // this.imageData = file.content
      this.imageSrc = file.content
      this.imgPreview = true
    },
    // 发送文字消息
    sendText() {
      if (!this.person) {
        this.textMsg = '' //清空输入框
        this.$toast('请点击上方提示框切换至人工服务')
        return
      }
      if (!this.serviceInter) {
        this.textMsg = '' //清空输入框
        this.$toast('暂未接入客服')
        return
      }
      if (!this.textMsg) {
        return
      }
      let content = this.textMsg.replace(/[\r\n]/g, '<br/>').replace(/\s/g, '&nbsp;')
      let msg = { text: content }
      this.sendMsg(msg, 'text')
      this.$refs['textarea'].focus()
      this.textMsg = '' //清空输入框
    },
    // 发送消息
    sendMsg(content, type) {
      // type="text|img|voice|comment"
      let contentType = ''
      if (type === 'text') contentType = '0x40'
      if (type === 'img') contentType = '0x44'
      if (type === 'comment') contentType = '0x58'
      // 发送消息
      let params = {
        contentType,
        content: content.url || content.text,
      }
      if (this.wsOpen) {
        wsSend(this.socketTask, params) //小会场
      } else {
        wsSend(this.bigSocketTask, params) //主会场
      }
    },
    // 添加文字消息到列表
    addTextMsg(msg) {
      this.msgList.push(msg)
    },
    // 添加语音消息到列表
    addVoiceMsg(msg) {
      this.msgList.push(msg)
    },
    // 添加图片消息到列表
    addImgMsg(msg) {
      msg.msg.content = this.setPicSize(msg.msg.content)
      this.msgImgList.push(msg.msg.content.url)
      this.msgList.push(msg)
    },
    addLinkMsg(msg) {
      this.msgList.push(msg)
    },
    // 添加系统文字消息到列表
    addSystemTextMsg(msg) {
      this.msgList.push(msg)
    },
    sendSystemMsg(content, type) {
      let lastid = this.msgList[this.msgList.length - 1].msg.id
      lastid + 1
      let row = {
        type: 'system',
        msg: { id: lastid, type: type, content: content },
      }
      this.screenMsg(row)
    },
    // 预览图片
    showPic() {
      ImagePreview(this.msgImgList)
    },
    onComment() {
      if (!this.serviceInter) {
        this.$toast('暂未接入客服')
        return
      }
      if (this.hasComment) {
        this.$toast('您已评价')
        return
      }
      this.commentInfo = {
        meetingId: this.meetingId,
        waiter: this.waiterId,
        member: this.ID,
      }
      this.commentShow = true
    },
    onPreview(param) {
      this.imgPreview = false
      if (param) {
        canvasDataURL(this.imageSrc, { quality: 0.7 }, (afterImgData) => {
          // console.log('afterImgData', afterImgData)
          let img = afterImgData.split(',')[1]
          this.imgUpload(img)
        })
      }
    },
    imgUpload(imgData) {
      this.$toast.loading({
        duration: 0, // 持续展示 toast
        forbidClick: true,
        message: '上传中',
      })
      const file = dataURLtoFile(imgData, 'fileName')
      let form = new FormData()
      form.append('file', file)
      let data = {
        meetingId: this.meetingId,
        memberId: this.ID,
        waiterId: this.waiterId,
        contentType: 12,
        content: '',
      }
      const params = JSON.stringify(msgBody(data))
      form.append('body', params)
      netUploadFile(form)
        .then((res) => {
          const { data } = res
          let msg = { url: data[0].url }
          this.sendMsg(msg, 'img')
          this.$toast.clear()
        })
        .catch(() => {
          this.$toast.clear()
          this.$toast('上传失败')
        })
    },
    // 继续
  },
}
</script>
<style lang="scss">
@import '@/assets/css/style.scss';
.rich-text {
  word-break: break-word;
}
.person-btn {
  margin-top: 10px;
  font-size: 14px;
  color: #72819b;
  padding: 10px;
  background: #ffffff;
  border: 0 solid #ccd3e5;
  border-radius: 4px;
  box-sizing: border-box;
  .btn-text {
    color: #1f6aff;
  }
}
.pull-tip {
  width: 100%;
  font-size: 10px;
  text-align: center;
  padding-top: 8px;
  color: #aaa;
}
.system-text {
  font-size: 10px;
}
.pull-loading {
  text-align: center;
  margin-top:8px;
}
.comment {
  position: fixed;
  bottom: 1px;
  z-index: 1000;
  width: 100%;
}
.queue-msg {
  position: absolute;
  top: 20px;
  background: rgba(126, 159, 246, 0.2);
  border-radius: 6px 6px 6px 0;
  color: #333333;
  max-width: 70%;
  min-height: 25px;
  padding: 10px;
  display: -webkit-box;
  display: -webkit-flex;
  display: flex;
  -webkit-box-align: center;
  -webkit-align-items: center;
  align-items: center;
  font-size: 14px;
  word-break: break-word;
  .queue-num {
    color: #1f6aff;
    font-weight: 700;
  }
}
</style>
